package com.cloneoner.test
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.PixelSnapping;
	import flash.display.Sprite;
	import flash.events.Event;

	/**
	 * @author Thibault Loup
	 */
	public class BmpMediaViewer extends Bitmap
	{
		
		/*
		 * TODO find the real coeff !!!
		 */
		// __________________________________________________________
		// -										 	  CONSTRUCTOR
		public function BmpMediaViewer(pWidth : int, pHeight : int)
		{
			_width = pWidth;
			_height = pHeight;

			super(null, PixelSnapping.AUTO, true);

			_build();
		}
		
		// __________________________________________________________
		// -										  PUBLICS METHODS
		
		public function add(pItem : DisplayObject, pDuration : Number) : void
		{
			_fcount = 0;
			_timeDuration = pDuration < 0 ? 0 : pDuration;
			_frameDuration = _fr > 0 ? _fr * _timeDuration : 31 * _timeDuration;
			
			_cleanCont();
			
			_current = pItem;
			_cont.addChild(_current);
			
			_repos();
			
			if ( _frameDuration == 0)
				_render();
			else
				addEventListener(Event.ENTER_FRAME, _onEnterFrame);
		}
		
		public function dispose() : void
		{
			removeEventListener(Event.ADDED_TO_STAGE, _onAdded);
			removeEventListener(Event.ENTER_FRAME, _onEnterFrame);

			_cleanCont();

			if ( _bmpd)
				_bmpd.dispose();

			_cont = null;
			_bmpd = null;
			_current = null;
		}
		
		// __________________________________________________________
		// -										 		   EVENTS
		
		private function _onAdded(event : Event) : void
		{
			removeEventListener(Event.ADDED_TO_STAGE, _onAdded);

			_fr = stage.frameRate;
		}
		
		private function _onEnterFrame(event : Event) : void
		{
			if ( _fcount >= _frameDuration )
			{
				removeEventListener(Event.ENTER_FRAME, _onEnterFrame);
				dispatchEvent(new Event(Event.COMPLETE));
			}
			
			if ( !_current ) return;
			
			_ratio = _easeOut(_fcount, _frameDuration);
			_current.alpha = _ratio*.1;
			
			_render();
			
			++_fcount;
		}
		
		// __________________________________________________________
		// -										 PRIVATES METHODS
		
		private function _build() : void
		{
			_cont = new Sprite();
			_bmpd = new BitmapData(_width, _height);

			bitmapData = _bmpd;

			addEventListener(Event.ADDED_TO_STAGE, _onAdded);
		}
		
		protected function _render() : void
		{
			_bmpd.lock();
			_bmpd.draw(_cont);
			_bmpd.unlock();
		}
		
		private function _repos() : void
		{
			if ( !_current ) return;
			
			var scx : Number = _width / _current.width;
			var scy : Number = _height / _current.height;
			var sc : Number = scx > scy ? scx : scy;
			
			_current.width *= sc;
			_current.height *= sc;
			_current.x = ( _width - _current.width ) >> 1;
			_current.y = ( _height - _current.height ) >> 1;
		}
		
		private function _easeOut(t : Number, d : Number) : Number
		{
			// TODO choose a EASE
			// Cubic
			// return -1 * (t /= d) * (t - 2);
			// Linear
			return t / d;
		}
		
		private function _cleanCont() : void
		{
			var c : DisplayObject;
			
			while (_cont.numChildren)
			{
				c = _cont.removeChildAt(0);
				if ( c is Bitmap) Bitmap(c).bitmapData.dispose();
				c = null;
			}
			
			_current = null;
		}		
		
		/* CONTENT */
		private var _cont : Sprite;
		private var _current : DisplayObject;
		protected var _bmpd : BitmapData;

		/* VAR */
		protected var _width : int;
		protected var _height : int;
		private var _frameDuration : Number;
		private var _timeDuration:Number;
		private var _fr : int;
		private var _fcount : int;
		protected var _ratio : Number = 0;
		private var _coeff:Number = 1;
	}
}